package cn.hyatt.auth.config;

import cn.hyatt.auth.security.filter.JwtAuthenticatedFilter;
import cn.hyatt.auth.security.handler.AuthAccessDeniedHandler;
import cn.hyatt.auth.security.service.AuthUserDetailsService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * Security 配置
 *
 * @author hyatt
 */
@Configuration
@EnableWebSecurity(debug = true)
public class SecurityConfig {

    @Resource
    private JwtProperties jwtProperties;
    @Resource
    private AuthUserDetailsService userDetailsService;
    @Resource
    private JwtAuthenticatedFilter jwtAuthenticatedFilter;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
        // 添加过滤-在用户名密码身份验证过滤器之前
        httpSecurity.addFilterBefore(jwtAuthenticatedFilter, UsernamePasswordAuthenticationFilter.class);

        // 异常处理
        httpSecurity.exceptionHandling(exceptionHandlingCustomizer -> exceptionHandlingCustomizer
                // 访问被拒绝处理程序
                .accessDeniedHandler(new AuthAccessDeniedHandler())
        );

        return httpSecurity
                // 禁用 csrf
                .csrf(AbstractHttpConfigurer::disable)
                // 授权 Http 请求
                .authorizeHttpRequests(authorizationManagerRequestMatcherRegistry -> authorizationManagerRequestMatcherRegistry
                        // 请求匹配-这些请求全部运行访问
                        .requestMatchers("/error", "/login", "/refreshAuth", "/imageCaptcha", "/base64Captcha").permitAll()
                        // 任何请求-需要认证
                        .anyRequest().authenticated()
                )
                .build();
    }

    @Bean
    public AuthenticationManager authenticationManager() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService);
        authenticationProvider.setPasswordEncoder(passwordEncoder());

        ProviderManager providerManager = new ProviderManager(authenticationProvider);
        providerManager.setEraseCredentialsAfterAuthentication(false);

        return providerManager;
    }

    /**
     * 密码处理器
     *
     * @return 结果
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
